package com.feib.stms.action;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.context.support.ResourceBundleMessageSource;

import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.DontBind;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.integration.spring.SpringBean;
import net.sourceforge.stripes.validation.DateTypeConverter;
import net.sourceforge.stripes.validation.Validate;

import com.feib.stms.model.Group;
import com.feib.stms.model.Securities;
import com.feib.stms.model.UploadFile;
import com.feib.stms.model.User;
import com.feib.stms.pagination.PaginatedList;
import com.feib.stms.service.BusinessDayService;
import com.feib.stms.service.GroupService;
import com.feib.stms.service.UploadFileService;
import com.feib.stms.util.StmsUtil;
import com.feib.stms.util.UserUtil;

/**
 * 
 * @title (#).java<br>
 * @description 上傳檔案 檔案查詢 公用Controller<br/>
 * <li>使用單位及角色:
 * <ol>
 * <li>券商端、遠銀分行。</li>
 * </ol></li>

 * </ul>
 * @author Jeff Gu
 * @version 1.0.0 2012/06/18
 * @copyright Far Eastern International Bank Copyright (c) 2012<br>
 * 
 */
public abstract class BaseQueryByUploadFileActionbean extends BaseActionBean{

	/**
	 * 起始頁<br/>
	 * EX:stms2006.jsp
	 * @return
	 */
	protected abstract String getDefaultPage();

	/**
	 * 上傳檔案類型
	 * 目前一個功能只會出現一種類型<br/>
	 * @return
	 */
	public abstract String getUploadFileFormat();


	protected static Map<String, String> SORT_FIELD_NAMES = new LinkedHashMap<String, String>();
	static{

		//放行清單畫面
		SORT_FIELD_NAMES.put("fileName", "FILE_NAME");//放行資料
		SORT_FIELD_NAMES.put("totalItems", "TOTAL_ITEMS");//淨收筆數
		SORT_FIELD_NAMES.put("totalnetIncome", "TOTAL_NET_INCOME"); // 淨收金額
		SORT_FIELD_NAMES.put("totalNetPayt", "TOTAL_NET_PAY");//淨付筆數
	}


	/**
	 * 查詢條件-交割日期迄
	 */
	@Validate( converter=DateTypeConverter.class)
	protected Date qryDeliveryDateFrom;

	/**
	 * 查詢條件-交割日期迄
	 */
	@Validate( converter=DateTypeConverter.class)
	protected Date qryDeliveryDateTo;


	/**
	 *畫面輸入查詢條件--區分分行跟券商身分用
	 */
	protected UploadFile qryUploadFile;

	/**
	 * 畫面上券商分公司checkbox
	 */
	protected List<Securities> securities;


	/**
	 * 查詢條件-分公司代號
	 */
	protected List<String> qrySecuritiesNos;

	/**
	 * 查詢條件-分公司代號全選 checkbox
	 */
	protected Boolean hideQryResultColumns = false;

	/**
	 * 查詢條件-只能查詢分公司的代號，系統控制
	 */
	protected List<String> userDealSecuritiesNos;


	/**
	 * 查詢結果(多筆)
	 */
	protected PaginatedList<UploadFile> queryResult;


	/**
	 * 查詢條件-檔案類型 
	 */
	protected List<String> fileFormats;


	/**
	 * 訊息-畫面顯示用
	 */
	protected String message;

	/**
	 * 錯誤訊息-畫面顯示用
	 */
	protected String errorMessage;


	@SpringBean("uploadFileService")
	private UploadFileService uploadFileService;


	@SpringBean("groupService")
	private GroupService groupService;

	@SpringBean("messageSource")
	protected ResourceBundleMessageSource messageSource;


    @SpringBean("businessDayService")
    private  BusinessDayService  businessDayService;
   
	
	

	@DontBind
	@DefaultHandler
	public Resolution doDefault()
	{
		logger.debug("Enter doDefault mehtod.");

		Date nextBusinessDay= businessDayService.getNextBusinessDay(new Date());
		
		if(null==nextBusinessDay){
			nextBusinessDay=new Date();
		}
		
		qryDeliveryDateFrom = nextBusinessDay;
		qryDeliveryDateTo = nextBusinessDay;
	
		if (!UserUtil.isBankGroup())
		{
			try {
				qryUploadFile = new UploadFile();
				qryUploadFile.setGroup(new Group());
				BeanUtils.copyProperties(UserUtil.getUserGroup(), qryUploadFile.getGroup(), new String[]{"users", "roles"});
			} catch (Exception e) {
			} 
		}
		return new ForwardResolution(getDefaultPage());
	}


	/**
	 * 查詢
	 * @return
	 */
	public Resolution doQuery()
	{
		logger.debug("Enter doQuery mehtod.");
		try {
			/* 設定換頁、排序等條件*/
			String sortCriterion = null == queryResult ? null : queryResult.getSortCriterion();
			List<String> sortFields = getSortFields();
			if (StringUtils.isEmpty(sortCriterion) || null == getSortFieldNames().get(sortCriterion)) // 未設定/找不到 排序條件時候，則以存款帳號為主要排序
				sortCriterion = sortFields.get(0);

			/* 銀行端一定要輸入群組代號 */
			if (UserUtil.isBankGroup() && "doQuery".equalsIgnoreCase(this.getContext().getEventName()))
			{
				if (null != qryUploadFile && null != qryUploadFile.getGroup() && null != qryUploadFile.getGroup().getGroupNo())
				{
					Group dbGroup = groupService.getByGroupNo(qryUploadFile.getGroup().getGroupNo());

					if (null == dbGroup)
					{
						this.errorMessage = "券商代號有誤！";
						return new ForwardResolution(getDefaultPage());
					}
					qryUploadFile.setGroup(dbGroup);
				}
				else
				{
					this.errorMessage = "請輸入券商代號！";
					return new ForwardResolution(getDefaultPage());
				}
			}

			if (null == this.qrySecuritiesNos) // 畫面沒選取
			{
				this.errorMessage = "請勾選分公司！";
				return new ForwardResolution(getDefaultPage());
			}

			if (null == qryUploadFile)
				qryUploadFile = new UploadFile();	



			List<String> constrainSecuritiesNos = new ArrayList<String>();
			PaginatedList<UploadFile> qryCondition = new PaginatedList<UploadFile>();
			setQueryCondition(qryCondition,constrainSecuritiesNos);



			/* 設定user可以查詢的 券商代號*/
			qryUploadFile.setUploadUser(new User());

			String securitiesNos="";
			for(String securitiesNo   :constrainSecuritiesNos){	
				logger.debug("securitiesNo {}",securitiesNo);

				securitiesNos+=securitiesNo+",";
			}
			securitiesNos=securitiesNos.substring(0, securitiesNos.length()-1).trim();

			logger.debug("securitiesNos {} ",securitiesNos);

			qryUploadFile.getUploadUser().setDealSecuritiesNos(securitiesNos);
			/* 設定user pk 判斷是否可以對檔案作操作 */
			qryUploadFile.getUploadUser().setUserPk(UserUtil.getUser().getUserPk());		
			logger.debug("qryDeliveryDateFrom {}",this.qryDeliveryDateFrom);
			logger.debug("qryDeliveryDateTo {}",this.qryDeliveryDateTo);
			this.queryResult = uploadFileService.findPaginatedListByUploadFile(qryUploadFile, null, null, this.qryDeliveryDateFrom, this.qryDeliveryDateTo, fileFormats, qryCondition);


			if (null == queryResult)
			{
				if(StringUtils.isNotEmpty(this.message)){
					this.message=this.message+"</br>";
				}else{
					this.message="";
				}
				this.message =this.message+messageSource.getMessage("query.nothing", null, "查無資料！", this.getContext().getRequest().getLocale());
				queryResult = new PaginatedList<UploadFile>(); 
				queryResult.setPageNumber(qryCondition.getPageNumber());
				queryResult.setPageSize(qryCondition.getPageSize());
			}

			this.queryResult.setSortCriterion(sortCriterion);
			this.queryResult.setSortDirection(qryCondition.getSortDirection());

		} catch (Exception e) {
			logger.error("查詢發生錯誤:",e);
		}
		return new ForwardResolution(getDefaultPage()); 
	}



	/**
	 * 檔案排序使用(非明細)
	 * @param qryCondition
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	protected void setQueryCondition(PaginatedList<UploadFile> qryCondition, List<String> constrainSecuritiesNos) throws InstantiationException, IllegalAccessException
	{
		logger.debug("Enter setQueryCondition(UploadFile) mehtod.");

		/* 設定換頁、排序等條件*/
		String sortCriterion = null == queryResult ? null : queryResult.getSortCriterion();
		List<String> sortFields = getSortFields();
		if (StringUtils.isEmpty(sortCriterion) || null == getSortFieldNames().get(sortCriterion)) // 未設定/找不到 排序條件時候，則以存款帳號為主要排序
			sortCriterion = sortFields.get(0);


		if (null != queryResult)
		{
			qryCondition.setPageNumber(queryResult.getPageNumber());
			qryCondition.setPageSize(queryResult.getPageSize());
			qryCondition.setSortCriterion(getSortFieldNames().get(sortCriterion));
			qryCondition.setSortDirection(queryResult.getSortDirection());
		}


		if (null == queryResult || StringUtils.isEmpty(queryResult.getSortCriterion()) || !sortFields.contains(queryResult.getSortCriterion()))
		{
			// 以存款帳號由大到小排序
			qryCondition.setSortCriterion(getSortFieldNames().get(sortFields.get(0)));
			qryCondition.setSortDirection(PaginatedList.SORT_DIRECTION_DESC);
		}
		if (null == qryUploadFile)
			this.qryUploadFile = new UploadFile();

		if (null == this.qrySecuritiesNos)
			this.qrySecuritiesNos = new ArrayList<String>();

		if (! UserUtil.isBankGroup())
		{
			// 非銀行端需加入 群組/證券業者 Group 限制
			qryUploadFile.setGroup(new Group());
			BeanUtils.copyProperties(UserUtil.getUserGroup(), qryUploadFile.getGroup(), new String[]{"users", "roles"});

			/* 加入查詢人員所能查詢的項目的限制   */
			// 由APP_USER中 取得查詢人於可查的分公司代號
			userDealSecuritiesNos = new ArrayList<String>();
			String[] securitiesNos = null;
			if (StringUtils.isNotEmpty(UserUtil.getUser().getDealSecuritiesNos()))
				securitiesNos = UserUtil.getUser().getDealSecuritiesNos().split(","); // 拆解

			if (!ArrayUtils.isEmpty(securitiesNos))
			{
				for(String no : securitiesNos)
				{
					if (StringUtils.isNotEmpty(no))
					{
						userDealSecuritiesNos.add(no);
					}
				}
			}
			else
			{
				// 使用者沒有可查的分公司代號
				constrainSecuritiesNos.add("NO_AUTHORITY");
				return;
			}

			/* 取得交集 */
			final Iterator<String> iterator = userDealSecuritiesNos.iterator();

			while (iterator.hasNext()) {
				final String o = iterator.next();

				if (qrySecuritiesNos.contains(o)) {
					constrainSecuritiesNos.add(o);
				}
			}	

			if (CollectionUtils.isEmpty(constrainSecuritiesNos))
			{
				// 畫面上沒輸入任何分公司代號，強迫以使用者可查詢的代號為主
				constrainSecuritiesNos.addAll(userDealSecuritiesNos);
			}		
		}
		else
		{
			constrainSecuritiesNos.addAll(this.qrySecuritiesNos);
		}





	}



	public List<String> getSortFields()
	{
		List<String> result = new ArrayList<String>();
		CollectionUtils.addAll(result, getSortFieldNames().keySet().iterator()	);
		return result;
	}

	public void setNavigator()
	{
		if (null != queryResult)
		{
			int sortDirection = queryResult.getSortDirection();  //2 : ascending, else: descending
			String sortSpan = "<span class=\"ui-icon ui-icon-circle-triangle-n\"></span>"; //由小到大
			if (1 == sortDirection)
			{
				sortSpan = "<span class=\"ui-icon ui-icon-circle-triangle-s\"></span>"; //由大到小
			}

			String sortCriterion = queryResult.getSortCriterion();
			if (null!= sortCriterion && null != getSortFieldNames().get(sortCriterion))
			{
				this.getContext().getRequest().setAttribute(sortCriterion+"SortedClass", 1==sortDirection?"sortDesc":"sortAsc");
				this.getContext().getRequest().setAttribute(sortCriterion+"SortedSpan", sortSpan);
			}
			else
			{
				sortCriterion = getSortFields().get(0);
				this.getContext().getRequest().setAttribute(sortCriterion+"SortedClass", 1==sortDirection?"sortDesc":"sortAsc");
				this.getContext().getRequest().setAttribute(sortCriterion+"SortedSpan", sortSpan);
			}


			// 上下頁鈕處理
			int lastPageNumber = queryResult.getTotalPageCount();
			int currentPageNumber = queryResult.getPageNumber();
			int prePageNumber = currentPageNumber - 1;
			int nextPageNumber = currentPageNumber + 1;

			this.getContext().getRequest().setAttribute("lastPageNumber", new Integer(lastPageNumber));
			this.getContext().getRequest().setAttribute("currentPageNumber", new Integer(currentPageNumber));
			this.getContext().getRequest().setAttribute("prePageNumber", new Integer(prePageNumber));
			this.getContext().getRequest().setAttribute("nextPageNumber", new Integer(nextPageNumber));
		}
	}



	protected Map<String, String> getSortFieldNames(){
		return SORT_FIELD_NAMES;
	}



	/**
	 * 只顯示使用者可以查詢的母/分公司
	 * @return
	 */
	public List<Securities> getSecurities() {
		if (null == securities)
		{
			if (UserUtil.isBankGroup())
			{
				if (null != qryUploadFile && null != qryUploadFile.getGroup() && null != qryUploadFile.getGroup().getGroupPk())
					securities = StmsUtil.getInstance().getSecuritiesByGroupPk(qryUploadFile.getGroup().getGroupPk());
			}
			else
			{
				securities = new ArrayList<Securities>();
				List<Securities> tempSecurities = StmsUtil.getInstance().getSecuritiesByGroupPk(UserUtil.getUserGroup().getGroupPk());

				/* 加入查詢人員所能查詢的項目的限制   */
				// 由APP_USER中 取得查詢人於可查的分公司代號
				userDealSecuritiesNos = new ArrayList<String>();
				String[] securitiesNos = null;
				if (StringUtils.isNotEmpty(UserUtil.getUser().getDealSecuritiesNos()))
					securitiesNos = UserUtil.getUser().getDealSecuritiesNos().split(","); // 拆解

				if (!ArrayUtils.isEmpty(securitiesNos))
				{
					for(String no : securitiesNos)
					{
						if (StringUtils.isNotEmpty(no))
						{
							userDealSecuritiesNos.add(no);
						}
					}
				}

				/* 取得交集 */
				final Iterator<String> iterator = userDealSecuritiesNos.iterator();

				while (iterator.hasNext()) {
					final String o = iterator.next();

					for(Securities s: tempSecurities)
					{
						if (s.getSecuritiesNo().equalsIgnoreCase(o))
						{
							securities.add(s);
							break;
						}
					}		        
				}

				tempSecurities.clear();
				tempSecurities = null;
			}

		}

		return securities;
	}




	public String getMessage() {
		return message;
	}


	public String getErrorMessage() {
		return errorMessage;
	}

	/**
	 * @param qryUploadFile 的設定的 qryUploadFile
	 */
	public void setQryUploadFile(UploadFile qryUploadFile) {
		this.qryUploadFile = qryUploadFile;
	}

	/**
	 * @return qryUploadFile
	 */
	public UploadFile getQryUploadFile() {
		return qryUploadFile;
	}

	public PaginatedList<UploadFile> getQueryResult() {
		return queryResult;
	}

	public void setQueryResult(PaginatedList<UploadFile> queryResult) {
		this.queryResult = queryResult;
	}

	public List<String> getQrySecuritiesNos() {
		return qrySecuritiesNos;
	}

	public void setQrySecuritiesNos(List<String> qrySecuritiesNos) {
		this.qrySecuritiesNos = qrySecuritiesNos;
	}

	public Date getQryDeliveryDateFrom() {
		return qryDeliveryDateFrom;
	}

	public void setQryDeliveryDateFrom(Date qryDeliveryDateFrom) {
		this.qryDeliveryDateFrom = qryDeliveryDateFrom;
	}

	public Date getQryDeliveryDateTo() {
		return qryDeliveryDateTo;
	}

	public void setQryDeliveryDateTo(Date qryDeliveryDateTo) {
		this.qryDeliveryDateTo = qryDeliveryDateTo;
	}
}
